using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Diagnostics;

namespace IllSoft.Xvcc.Volano.Client
{
    public class Channel
    {
        #region Events

        /// <summary>
        /// Audio alarm
        /// </summary>
        public event EventHandler<AudioAlarmEventArgs> AudioAlarm;

        /// <summary>
        /// Channel joined
        /// </summary>
        public event EventHandler<ChannelEventArgs> Joined;

        /// <summary>
        /// Disconnected
        /// </summary>
        public event EventHandler<EventArgs> Disconnected;

        /// <summary>
        /// Channel message
        /// </summary>
        public event EventHandler<MessageEventArgs> Message;

        /// <summary>
        /// Channel parted
        /// </summary>
        public event EventHandler<PartEventArgs> Parted;

        /// <summary>
        /// Query
        /// </summary>
        public event EventHandler<QueryEventArgs> Query;

        /// <summary>
        /// User list
        /// </summary>
        public event EventHandler<UserListEventArgs> UserListReceived;

        #endregion

        #region Members

        private VolanoClient _volanoClient;

        private StringCollection _messageIgnoreList;
        private StringCollection _queryIgnoreList;

        #endregion

        #region (De-)Constructor(s)

        internal Channel(string name, VolanoClient volanoClient)
        {
            this.Name = name;
            this._volanoClient = volanoClient;
        }

        internal Channel(string name, User myself, VolanoClient volanoClient)
        {
            this.Name = name;
            this.Myself = myself;
            this._volanoClient = volanoClient;

            this._messageIgnoreList = new StringCollection();
            this._queryIgnoreList = new StringCollection();
        }

        #endregion

        #region Properties

        public string Handle { get; private set; }
        public User Myself { get; internal set; }
        public string Name { get; private set; }
        public Users Users { get; internal set; }

        #endregion

        #region Event Handlers

        protected internal virtual void OnAudioAlarm(AudioAlarmEventArgs e)
        {
            EventHandler<AudioAlarmEventArgs> handler = this.AudioAlarm;;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected internal virtual void OnDisconnected(EventArgs e)
        {
            EventHandler<EventArgs> handler = this.Disconnected;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected internal virtual void OnJoined(ChannelEventArgs e)
        {
            EventHandler<ChannelEventArgs> handler = this.Joined;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected internal virtual void OnMessage(MessageEventArgs e)
        {
            EventHandler<MessageEventArgs> handler = this.Message;

            switch (e.EventDetails)
            {
                case EventDetails.Someone:
                    if (!this._messageIgnoreList.Contains(e.User.Nick))
                    {
                        if (handler != null)
                        {
                            handler(this, e);
                        }
                    }
                    else
                    {
                        // TODO: Raise an event? MessageIgnored?
                        Debug.WriteLine(string.Format("IGNORED: <{0}> {1}", e.User, e.Message));
                    }
                    break;

                default:
                    break;
            }
        }

        protected internal virtual void OnParted(PartEventArgs e)
        {
            EventHandler<PartEventArgs> handler = this.Parted;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected internal virtual void OnQuery(QueryEventArgs e)
        {
            EventHandler<QueryEventArgs> handler = this.Query;

            this._volanoClient.SendQueryClose(this.Myself, e.OtherUser);

            Debug.WriteLine(string.Format("Blocked query from '{0}' in channel '{1}'", e.OtherUser.Nick, this.Name));

            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected internal virtual void OnUserListReceived(UserListEventArgs e)
        {
            EventHandler<UserListEventArgs> handler = this.UserListReceived;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region Methods

        public void IgnoreEverythingFrom(User user)
        {
            this.IgnoreMessagesFrom(user);
            this.IgnoreQueriesFrom(user);
        }

        public void IgnoreQueriesFrom(User user)
        {
            this._messageIgnoreList.Add(user.Nick);
        }

        public void IgnoreMessagesFrom(User user)
        {
            this._queryIgnoreList.Add(user.Nick);
        }

        public void Join()
        {
            this._volanoClient.SendChannelJoin(this, this.Myself);
        }

        public void Part()
        {
            this._volanoClient.SendChannelPart(this, this.Myself);
        }

        public void SendMessage(string message)
        {
            this._volanoClient.SendMessage(this, this.Myself, message);
        }

        #endregion
    }
}